package com.hitfm.iplay;

import java.io.IOException;
import java.util.Random;

import com.hitfm.iplay.util.BitmapRadius;
import com.hitfm.iplay.util.SDCardOperation;

import android.app.Service;
import android.content.Intent;
import android.content.res.Resources.NotFoundException;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;

public class MusicPlayerService extends Service {
	private final IBinder mBinder = new LocalBinder();

	private MediaPlayer mMediaPlayer = null;
	private boolean isRandom = true;

	public static final String PLAYER_PREPARE_END = "com.hitfm.iplay.prepared";
	public static final String PLAY_COMPLETED = "com.hitfm.iplay.playcompleted";
	public static final String PLAY_PAUSE = "com.hitfm.iplay.pause";
	public static final String PLAY_CONTINUE = "com.hitfm.iplay.continue";
	public static final String ERROR = "com.hitfm.iplay.error";
	public static final int RADIUS = 15;

	MediaPlayer.OnCompletionListener mCompleteListener = new MediaPlayer.OnCompletionListener() {
		public void onCompletion(MediaPlayer mp) {
			broadcastEvent(PLAY_COMPLETED);
		}
	};

	MediaPlayer.OnPreparedListener mPrepareListener = new MediaPlayer.OnPreparedListener() {
		public void onPrepared(MediaPlayer mp) {
			broadcastEvent(PLAYER_PREPARE_END);
		}
	};

	private String path;
	private int id;
	private boolean isPaused = false;
	private int albumID;

	private boolean isError = false;

	private static MusicPlayerApp musicPlayerApp = null;

	private void broadcastEvent(String what) {
		Intent i = new Intent(what);
		sendBroadcast(i);
	}

	public void onCreate() {
		super.onCreate();
		mMediaPlayer = new MediaPlayer();
		mMediaPlayer.setOnPreparedListener(mPrepareListener);
		mMediaPlayer.setOnCompletionListener(mCompleteListener);
	}

	public class LocalBinder extends Binder {
		public MusicPlayerService getService() {
			return MusicPlayerService.this;
		}
	}

	public IBinder onBind(Intent intent) {
		return mBinder;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		mMediaPlayer.stop();
	}

	public void setMusicPath(String path) {

		try {
			this.path = path;
			mMediaPlayer.reset();
			mMediaPlayer.setDataSource(path);
			mMediaPlayer.prepare();
		} catch (IOException e) {
			return;
		} catch (IllegalArgumentException e) {
			return;
		}
	}

	public void start() {
		if (isPaused) {
			broadcastEvent(PLAY_CONTINUE);
		}
		isPaused = false;
		mMediaPlayer.start();
	}

	public void stop() {
		isPaused = false;
		mMediaPlayer.stop();
	}

	public void pause() {
		isPaused = true;
		broadcastEvent(PLAY_PAUSE);
		mMediaPlayer.pause();
	}

	public boolean isPlaying() {
		return mMediaPlayer.isPlaying();
	}

	public int getDuration() {
		return mMediaPlayer.getDuration();
	}

	public int getPosition() {
		return mMediaPlayer.getCurrentPosition();
	}

	public void setPosition(int msec) {
		mMediaPlayer.seekTo(msec);
	}

	public long seek(long whereto) {
		mMediaPlayer.seekTo((int) whereto);
		return whereto;
	}

	public String getMusicPath() {
		return path;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	/**
	 * 
	 * @param isNext
	 *            true:next; false:pre
	 */
	public void nextOrPreSong(boolean isNext) {
		try {
			isError = false;
			musicPlayerApp = (MusicPlayerApp) getApplication();
			if (null == musicPlayerApp.getCursor()) {
				musicPlayerApp.initCursor();
			}
			Cursor mCursor = musicPlayerApp.getCursor();
			if (0 == mCursor.getCount()) {
				if (!SDCardOperation.IsExistSdCard()) {
					Toast.makeText(this, R.string.nosdcard, Toast.LENGTH_SHORT)
							.show();
				}
				return;
			}
			int temp = 0;
			if (isRandom) {
				Random random = new Random(System.currentTimeMillis());
				temp = random.nextInt(mCursor.getCount());
			} else if (isNext) {
				temp = ((id + 1) < mCursor.getCount()) ? (id + 1) : 0;
			} else if (!isNext) {
				temp = ((id - 1) >= 0) ? (id - 1) : (mCursor.getCount() - 1);
			}
			id = temp;
			if (mCursor.moveToPosition(id)) {
				String url = mCursor.getString(mCursor
						.getColumnIndex(MediaStore.Audio.Media.DATA));
				setMusicPath(url);
				albumID = mCursor
						.getInt(mCursor
								.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));
				mMediaPlayer.start();
			} else {
				Toast.makeText(this, R.string.nosong, Toast.LENGTH_SHORT)
						.show();
			}
		} catch (IllegalArgumentException e) {
			isError = true;
			e.printStackTrace();
		} catch (NotFoundException e) {
			isError = true;
			Toast.makeText(this, R.string.nosong, Toast.LENGTH_SHORT).show();
			e.printStackTrace();
		} catch (Exception e) {
			isError = true;
			Toast.makeText(this, R.string.unknowerror, Toast.LENGTH_SHORT)
					.show();
		} finally {
			if (null != mMediaPlayer && isError) {
				mMediaPlayer.stop();
				musicPlayerApp.closeCursor();
				broadcastEvent(ERROR);
			}
		}
	}

	public boolean isRandom() {
		return isRandom;
	}

	public void setRandom(boolean isRandom) {
		this.isRandom = isRandom;
	}

	public Bitmap getAlbumArt() {
		String album_art = null;
		try {
			int id = this.albumID;
			String mUriAlbums = "content://media/external/audio/albums";
			String[] projection = new String[] { "album_art" };
			Cursor cur = this.getContentResolver().query(
					Uri.parse(mUriAlbums + "/" + Integer.toString(id)),
					projection, null, null, null);
			if (cur.getCount() > 0 && cur.getColumnCount() > 0) {
				cur.moveToNext();
				album_art = cur.getString(0);
			}
			cur.close();
			cur = null;
		} catch (Exception e) {
			Toast.makeText(this, R.string.nosongimage, Toast.LENGTH_SHORT)
					.show();
		}
		if (album_art != null) {
			return BitmapRadius.toRoundCorner(
					BitmapFactory.decodeFile(album_art), RADIUS);
		} else {
			return null;
		}

	}

	public boolean isPaused() {
		return isPaused;
	}

}
